OpenSees.NET

Open System for Earthquake Engineering Simulation (OpenSees) in .NET Environment

What's OpenSees.NET?

OpenSees.NET is Microsoft .NET framework assembly as a Wrapper for OpenSees framework. OpenSees.NET developed by using C++/CLI technology for x86 and x64 architectures. We tried our best to make no significant changes to the original code. All minor changes applied by using the _DLL predefined macro. Most of these changes are because of difference between code generation runtime library of wrapper project and static link libraries of OpenSees. Regardless of these, All functionally and capabilities of OpenSees remain unchanged.

Download

Version Platform
OpenSees v.3.0.0a Windows 64bit,x64 download Source Code
OpenSees v.3.0.0a Windows 32bit,x86 download Source Code

Prerequisites :

Microsoft .NET Framework 3.5

Microsoft Visual C++ Redistributable for Visual Studio 2017

Tcl 8.6.8.0 Windows (64-bit, x64)

Example Code

                        
var theDomain = new OpenSees.Components.DomainWrapper();
var nodes = new OpenSees.Components.NodeWrapper[]
{
    new OpenSees.Components.NodeWrapper(1,3,0,0),
    new OpenSees.Components.NodeWrapper(2,3,0,3),
    new OpenSees.Components.NodeWrapper(3,3,0,3),
    new OpenSees.Components.NodeWrapper(4,3,4,3),
    new OpenSees.Components.NodeWrapper(5,3,4,0),
    new OpenSees.Components.NodeWrapper(6,3,2,3),
};
theDomain.AddNode(nodes);
var sps = new OpenSees.Components.Constraints.SP_ConstraintWrapper[]
{
    new OpenSees.Components.Constraints.SP_ConstraintWrapper(1, 0, 0.0, true),
    new OpenSees.Components.Constraints.SP_ConstraintWrapper(1, 1, 0.0, true),
    new OpenSees.Components.Constraints.SP_ConstraintWrapper(1, 2, 0.0, true),
    new OpenSees.Components.Constraints.SP_ConstraintWrapper(5, 0, 0.0, true),
    new OpenSees.Components.Constraints.SP_ConstraintWrapper(5, 1, 0.0, true),
    new OpenSees.Components.Constraints.SP_ConstraintWrapper(5, 2, 0.0, true),
};
theDomain.AddSP_Constraint(sps);

//equalDOF 2 3 1 2
var Ccr = new OpenSees.MatrixWrapper(2, 2);
Ccr.Zero(); Ccr[0, 0] = 1.0; Ccr[1, 1] = 1.0;
var rcDOF = new OpenSees.IDWrapper(2);
rcDOF[0] = 0;rcDOF[1] = 1;
theDomain.AddMP_Constraint(new OpenSees.Components.Constraints.MP_ConstraintWrapper(2, 3, Ccr, rcDOF, rcDOF));

var transftagCrdT = new OpenSees.Elements.CrdTransfs.LinearCrdTransf2dWrapper();
var e = 2.0e11;
var i = 6.572e-5;
var a = 4.265e-3;
var ele1 = new OpenSees.Elements.ElasticBeam2dWrapper(1, a, e, i, 1, 2, transftagCrdT, 0, 0, 0, 0);
var ele21 = new OpenSees.Elements.ElasticBeam2dWrapper(21, a, e, i, 3, 6, transftagCrdT, 0, 0, 0, 0);
var ele22 = new OpenSees.Elements.ElasticBeam2dWrapper(22, a, e, i, 6, 4, transftagCrdT, 0, 0, 0, 0);
var ele3 = new OpenSees.Elements.ElasticBeam2dWrapper(3, a, e, i, 4, 5, transftagCrdT, 0, 0, 0, 0);
theDomain.AddElement(ele1);
theDomain.AddElement(ele21);
theDomain.AddElement(ele22);
theDomain.AddElement(ele3);

//recorder Node -file opensees.net_results/opensees.net_disp_6.out -time -node 6 -dof 1 2 3 disp
var savepath = System.Environment.CurrentDirectory + "\\opensees.net_results\\";
if (!System.IO.Directory.Exists(savepath))
    System.IO.Directory.CreateDirectory(savepath);
var dirIds2 = new OpenSees.IDWrapper(new int[] { 0, 1, 2 });
var nodeTag = 6;
var opsstream = new OpenSees.Handlers.DataFileStreamWrapper(savepath + $"\\opensees.net_disp_{nodeTag}.txt");
var recorder = new OpenSees.Recorders.NodeRecorderWrapper(
    dirIds2,
    new OpenSees.IDWrapper(new int[] { nodeTag }),
    0,
    "disp",
    theDomain,
    opsstream
);
theDomain.AddRecorder(recorder);

// create linear pattern
var theSeries = new OpenSees.Components.Timeseries.LinearSeriesWrapper();
var theLoadPattern = new OpenSees.Components.LoadPatterns.LoadPatternWrapper(1);
theLoadPattern.SetTimeSeries(theSeries);
theDomain.AddLoadPattern(theLoadPattern);

//$Wx mag of uniformily distributed ref load acting in direction along member length
//$Wy mag of uniformily distributed ref load acting in local y direction of element
//$Wz mag of uniformily distributed ref load acting in local z direction of element
//$Py mag of ref point load acting in direction along member length
//$Py mag of ref point load acting in local y direction of element
//$Pz mag of ref point load acting in local z direction of element
//$xL location of point load relative to node I, prescribed as fraction of element length

var wt = -5.0e4; // $Wy
var wa = 0; // $Wx

theDomain.AddElementLoad(new OpenSees.Components.Loads.Beam2dUniformLoadWrapper(1, wt, wa, 21), 1);
theDomain.AddElementLoad(new OpenSees.Components.Loads.Beam2dUniformLoadWrapper(2, wt, wa, 22), 1);

// for partial load use Beam2dPartialUniformLoadWrapper

var theModel = new OpenSees.AnalysisModelWrapper();

/*
#define CURRENT_TANGENT 0
#define INITIAL_TANGENT 1
#define CURRENT_SECANT  2
#define INITIAL_THEN_CURRENT_TANGENT  3
#define NO_TANGENT  4
#define SECOND_TANGENT 5
#define HALL_TANGENT 6
*/
var theSolnAlgo = new OpenSees.Algorithms.ModifiedNewtonWrapper(0 /*CURRENT_TANGENT*/);

var theIntegrator = new OpenSees.Integrators.Static.LoadControlWrapper(1, 1, 1, 1);
var theHandler = new OpenSees.Handlers.TransformationConstraintHandlerWrapper();
var theRCM = new OpenSees.GraphNumberers.RCMWrapper(false);
var theNumberer = new OpenSees.Numberers.DOF_NumbererWrapper(theRCM);
var theSolver = new OpenSees.Systems.Linears.BandGenLinLapackSolverWrapper();
var theSOE = new OpenSees.Systems.Linears.BandGenLinSOEWrapper(theSolver);
var test = new OpenSees.ConvergenceTests.CTestNormDispIncrWrapper(1e-8, 6, 2, 2, 1.0e10);
var theAnalysis = new OpenSees.Analysis.StaticAnalysisWrapper(
    theDomain,
    theHandler,
    theNumberer,
    theModel,
    theSolnAlgo,
    theSOE,
    theIntegrator,
    test
);

theAnalysis.Analyze(1);


// equal to loadConst -time 0.0
theDomain.SetLoadConst(); // loadConst
theDomain.SetCurrentTime(0); // -time 0.0
theDomain.SetCommittedTime(0); // -time 0.0

Console.ReadKey();
                        
                    
                        
# Aryan Rezaie Rad, EPFL, Suisse, 2018
wipe
file mkdir opensees_results
model basic -ndm 2 -ndf 3
set e 2.e11
set i 6.572e-5
set a 4.265e-3
node 1 0. 0.
node 2 0. 3.
node 3 0. 3.
node 4 4. 3.
node 5 4. 0.
node 6 2. 3.

fix 1 1 1 1
fix 5 1 1 1

equalDOF 2 3 1 2

set transftag 1
geomTransf Linear $transftag
element elasticBeamColumn 1 1 2 $a $e $i $transftag



element elasticBeamColumn 21 3 6 $a $e $i $transftag
element elasticBeamColumn 22 6 4 $a $e $i $transftag

element elasticBeamColumn 3 4 5 $a $e $i $transftag

#recorder Node -file data/node1.out -time -node 1 -dof 1 2 reaction
#recorder Node -file data/node5.out -time -node 5 -dof 1 2 reaction
recorder Node -file opensees_results/opensees_disp_6.txt -time -node 6 -dof 1 2 3 disp
#recorder Node -file data/node2disp.out -time -node 2 -dof 1 2 3 disp

puts "model build!"

pattern Plain 2 Linear {
    eleLoad -ele 21 22 -type -beamUniform -5e4
}
constraints Plain
numberer Plain
system BandGeneral
test NormDispIncr 1.e-8 6
algorithm ModifiedNewton
integrator LoadControl 1
analysis Static
analyze 1
loadConst -time 0.0
                            
                    
                            

NET.addAssembly('System');
NET.addAssembly('System.IO');
NET.addAssembly(strcat(pwd,'\OpenSees.NET.X64.dll'));

theDomain = OpenSees.Components.DomainWrapper();
theDomain.AddNode(OpenSees.Components.NodeWrapper(1,3,0,0));
theDomain.AddNode(OpenSees.Components.NodeWrapper(2,3,0,3));
theDomain.AddNode(OpenSees.Components.NodeWrapper(3,3,0,3));

node = OpenSees.Components.NodeWrapper(4,3,4,3);
theDomain.AddNode(node);
theDomain.AddNode(OpenSees.Components.NodeWrapper(5,3,4,0));
theDomain.AddNode(OpenSees.Components.NodeWrapper(6,3,2,3));

theDomain.AddSP_Constraint(OpenSees.Components.Constraints.SP_ConstraintWrapper(1, 0, 0.0, true));
theDomain.AddSP_Constraint(OpenSees.Components.Constraints.SP_ConstraintWrapper(1, 1, 0.0, true));
theDomain.AddSP_Constraint(OpenSees.Components.Constraints.SP_ConstraintWrapper(1, 2, 0.0, true));
theDomain.AddSP_Constraint(OpenSees.Components.Constraints.SP_ConstraintWrapper(5, 0, 0.0, true));
theDomain.AddSP_Constraint(OpenSees.Components.Constraints.SP_ConstraintWrapper(5, 1, 0.0, true));
theDomain.AddSP_Constraint(OpenSees.Components.Constraints.SP_ConstraintWrapper(5, 2, 0.0, true));

Ccr = OpenSees.MatrixWrapper(2, 2);
Ccr.Zero();
Ccr.Set(0, 0, 1.0);
Ccr.Set(1, 1, 1.0);
rcDOF = OpenSees.IDWrapper(2);
rcDOF.Set(0,0);
rcDOF.Set(1,1);
theDomain.AddMP_Constraint(OpenSees.Components.Constraints.MP_ConstraintWrapper(2, 3, Ccr, rcDOF, rcDOF));

transftagCrdT = OpenSees.Elements.CrdTransfs.LinearCrdTransf2dWrapper();

e = 2.0e11;
i = 6.572e-5;
a = 4.265e-3;

ele1 =  OpenSees.Elements.ElasticBeam2dWrapper(1, a, e, i, 1, 2, transftagCrdT, 0, 0, 0, 0);
ele21 =  OpenSees.Elements.ElasticBeam2dWrapper(21, a, e, i, 3, 6, transftagCrdT, 0, 0, 0, 0);
ele22 =  OpenSees.Elements.ElasticBeam2dWrapper(22, a, e, i, 6, 4, transftagCrdT, 0, 0, 0, 0);
ele3 =  OpenSees.Elements.ElasticBeam2dWrapper(3, a, e, i, 4, 5, transftagCrdT, 0, 0, 0, 0);

theDomain.AddElement(ele1);
theDomain.AddElement(ele21);
theDomain.AddElement(ele22);
theDomain.AddElement(ele3);

savepath = strcat(char(System.Environment.CurrentDirectory),'\opensees.net_results\');
isExist = double(System.IO.Directory.Exists(savepath));
if isExist == 0
    System.IO.Directory.CreateDirectory(savepath);
end
dirIds2 = OpenSees.IDWrapper(3);
dirIds2.Set(0,0);
dirIds2.Set(1,1);
dirIds2.Set(2,2);

nodeTag = 6;
recNodes = OpenSees.IDWrapper(1);
recNodes.Set(0,nodeTag);


filename = strcat(savepath , 'opensees.net_disp_',int2str(nodeTag),'.txt');
opsstream = OpenSees.Handlers.DataFileStreamWrapper(filename);
recorder = OpenSees.Recorders.NodeRecorderWrapper(dirIds2,recNodes,0,'disp',theDomain,opsstream);
theDomain.AddRecorder(recorder);

theSeries = OpenSees.Components.Timeseries.LinearSeriesWrapper();
theLoadPattern = OpenSees.Components.LoadPatterns.LoadPatternWrapper(1);
theLoadPattern.SetTimeSeries(theSeries);
theDomain.AddLoadPattern(theLoadPattern);

%$Wx mag of uniformily distributed ref load acting in direction along member length
%$Wy mag of uniformily distributed ref load acting in local y direction of element
%$Wz mag of uniformily distributed ref load acting in local z direction of element
%$Py mag of ref point load acting in direction along member length
%$Py mag of ref point load acting in local y direction of element
%$Pz mag of ref point load acting in local z direction of element
%$xL location of point load relative to node I, prescribed as fraction of element length

wt = -5.0e4; % $Wy
wa = 0; % $Wx

theDomain.AddElementLoad(OpenSees.Components.Loads.Beam2dUniformLoadWrapper(1, wt, wa, 21), 1);
theDomain.AddElementLoad(OpenSees.Components.Loads.Beam2dUniformLoadWrapper(2, wt, wa, 22), 1);

% for partial load use Beam2dPartialUniformLoadWrapper

theModel = OpenSees.AnalysisModelWrapper();

%  #define CURRENT_TANGENT 0
%  #define INITIAL_TANGENT 1
%  #define CURRENT_SECANT  2
%  #define INITIAL_THEN_CURRENT_TANGENT  3
%  #define NO_TANGENT  4
%  #define SECOND_TANGENT 5
%  #define HALL_TANGENT 6
theSolnAlgo = OpenSees.Algorithms.ModifiedNewtonWrapper(0);   %CURRENT_TANGENT

theIntegrator = OpenSees.Integrators.Static.LoadControlWrapper(1, 1, 1, 1);
theHandler = OpenSees.Handlers.TransformationConstraintHandlerWrapper();
theRCM = OpenSees.GraphNumberers.RCMWrapper(false);
theNumberer = OpenSees.Numberers.DOF_NumbererWrapper(theRCM);
theSolver = OpenSees.Systems.Linears.BandGenLinLapackSolverWrapper();
theSOE = OpenSees.Systems.Linears.BandGenLinSOEWrapper(theSolver);
test = OpenSees.ConvergenceTests.CTestNormDispIncrWrapper(1e-8, 6, 2, 2, 1.0e10);

theAnalysis = OpenSees.Analysis.StaticAnalysisWrapper( ...
    theDomain,...
    theHandler,...
    theNumberer,...
    theModel,...
    theSolnAlgo,...
    theSOE,...
    theIntegrator,...
    test...
);
theAnalysis.Analyze(1);
nodedisp = node.GetDisp();
disp('NODE4 DISPs:');
disp(double(nodedisp));
theAnalysis.Wipe();


                            
                    

Recent Posts

Three-Dimensional rigid Frame subjected to bi-directional earthquake ground motion
Three-Dimensional rigid Frame subjected to bi-directional earthquake ground motionclose

The model consists of three stories and one bay in each direction. Rigid diaphragm multi-point constraints are used to enforce the rigid in-plane stiffness assumption for the floors. Gravity loads are applied to the structure and the 1978 Tabas acceleration records are the uniform earthquake excitations.

Our Team

M. Salehi
MSc in Structural Engineering
Ferdowsi Univeristy of Mashhad