1 | /*
|
---|
2 | * \file Constraints.c
|
---|
3 | * \brief: implementation of the Constraints class, derived from DataSet class
|
---|
4 | */
|
---|
5 |
|
---|
6 | /*Headers: {{{1*/
|
---|
7 | #ifdef HAVE_CONFIG_H
|
---|
8 | #include "config.h"
|
---|
9 | #else
|
---|
10 | #error "Cannot compile with HAVE_CONFIG_H symbol! run configure first!"
|
---|
11 | #endif
|
---|
12 |
|
---|
13 | #include <vector>
|
---|
14 | #include <functional>
|
---|
15 | #include <algorithm>
|
---|
16 | #include <iostream>
|
---|
17 |
|
---|
18 | #include "./DataSet.h"
|
---|
19 | #include "../shared/shared.h"
|
---|
20 | #include "../include/include.h"
|
---|
21 | #include "../EnumDefinitions/EnumDefinitions.h"
|
---|
22 |
|
---|
23 | using namespace std;
|
---|
24 | /*}}}*/
|
---|
25 |
|
---|
26 | /*Object constructors and destructor*/
|
---|
27 | /*FUNCTION Constraints::Constraints(){{{1*/
|
---|
28 | Constraints::Constraints(){
|
---|
29 | return;
|
---|
30 | }
|
---|
31 | /*}}}*/
|
---|
32 | /*FUNCTION Constraints::Constraints(int in_enum){{{1*/
|
---|
33 | Constraints::Constraints(int in_enum): DataSet(in_enum){
|
---|
34 | //do nothing;
|
---|
35 | return;
|
---|
36 | }
|
---|
37 | /*}}}*/
|
---|
38 | /*FUNCTION Constraints::~Constraints(){{{1*/
|
---|
39 | Constraints::~Constraints(){
|
---|
40 | return;
|
---|
41 | }
|
---|
42 | /*}}}*/
|
---|
43 |
|
---|
44 | /*Numerics: */
|
---|
45 | /*FUNCTION Constraints::NumberOfLocalRgbs{{{1*/
|
---|
46 | int Constraints::NumberOfLocalRgbs(int analysis_type){
|
---|
47 |
|
---|
48 | int i;
|
---|
49 | int count=0;
|
---|
50 |
|
---|
51 | for(i=0;i<this->Size();i++){
|
---|
52 |
|
---|
53 | Object* object=(Object*)this->GetObjectByOffset(i);
|
---|
54 |
|
---|
55 | /*Check this is a single point constraint (spc): */
|
---|
56 | if (object->Enum()==RgbEnum){
|
---|
57 |
|
---|
58 | Rgb* rgb=(Rgb*)object;
|
---|
59 | if(rgb->InAnalysis(analysis_type))count++;
|
---|
60 | }
|
---|
61 | }
|
---|
62 |
|
---|
63 | return count;
|
---|
64 | }
|
---|
65 | /*}}}*/
|
---|
66 | /*FUNCTION Constraints::NumberOfConstraints{{{1*/
|
---|
67 | int Constraints::NumberOfConstraints(void){
|
---|
68 |
|
---|
69 | int localconstraints;
|
---|
70 | int numberofconstraints;
|
---|
71 |
|
---|
72 | /*Get number of local constraints*/
|
---|
73 | localconstraints=this->Size();
|
---|
74 |
|
---|
75 | /*figure out total number of constraints combining all the cpus (no clones here)*/
|
---|
76 | #ifdef _PARALLEL_
|
---|
77 | MPI_Reduce(&localconstraints,&numberofconstraints,1,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD );
|
---|
78 | MPI_Bcast(&numberofconstraints,1,MPI_INT,0,MPI_COMM_WORLD);
|
---|
79 | #else
|
---|
80 | numberofconstraints=localconstraints;
|
---|
81 | #endif
|
---|
82 |
|
---|
83 | return numberofconstraints;
|
---|
84 | }
|
---|
85 | /*}}}*/
|
---|
86 | /*FUNCTION Constraints::SetupSpcs{{{1*/
|
---|
87 | void Constraints::SetupSpcs(Nodes* nodes,Vec yg,int analysis_type){
|
---|
88 |
|
---|
89 | int i;
|
---|
90 |
|
---|
91 | Node* node=NULL;
|
---|
92 | int nodeid;
|
---|
93 | int dof;
|
---|
94 | double value;
|
---|
95 |
|
---|
96 | for(i=0;i<this->Size();i++){
|
---|
97 |
|
---|
98 | Object* object=(Object*)this->GetObjectByOffset(i);
|
---|
99 |
|
---|
100 | /*Check this is a single point constraint (spc): */
|
---|
101 | if(object->Enum()==SpcEnum){
|
---|
102 |
|
---|
103 | Spc* spc=(Spc*)object;
|
---|
104 |
|
---|
105 | if(spc->InAnalysis(analysis_type)){
|
---|
106 |
|
---|
107 | /*Ok, this object is a constraint. Get the nodeid from the node it applies to: */
|
---|
108 | nodeid=spc->GetNodeId();
|
---|
109 | dof=spc->GetDof();
|
---|
110 | value=spc->GetValue();
|
---|
111 |
|
---|
112 | /*Now, chase through nodes and find the corect node: */
|
---|
113 | node=(Node*)nodes->GetObjectById(NULL,nodeid);
|
---|
114 |
|
---|
115 | /*Apply constraint: */
|
---|
116 | if(node){ //in case the spc is dealing with a node on another cpu
|
---|
117 | node->ApplyConstraint(yg,dof,value);
|
---|
118 | }
|
---|
119 | }
|
---|
120 |
|
---|
121 | }
|
---|
122 | }
|
---|
123 |
|
---|
124 | /*Assemble yg: */
|
---|
125 | VecAssemblyBegin(yg);
|
---|
126 | VecAssemblyEnd(yg);
|
---|
127 | }
|
---|
128 | /*}}}*/
|
---|
129 | /*FUNCTION Constraints::SetupMpcs{{{1*/
|
---|
130 | void Constraints::SetupMpcs(Mat Rmg,Nodes* nodes,int analysis_type){
|
---|
131 |
|
---|
132 | int i;
|
---|
133 |
|
---|
134 | int nodeid1;
|
---|
135 | int nodeid2;
|
---|
136 | int dof;
|
---|
137 |
|
---|
138 | int dof1;
|
---|
139 | int dof2;
|
---|
140 |
|
---|
141 |
|
---|
142 | Node* node1=NULL;
|
---|
143 | Node* node2=NULL;
|
---|
144 |
|
---|
145 | int count=-1;
|
---|
146 |
|
---|
147 | for(i=0;i<this->Size();i++){
|
---|
148 |
|
---|
149 | Object* object=(Object*)this->GetObjectByOffset(i);
|
---|
150 |
|
---|
151 | /*Check this is a mutiple point constraint (spc): */
|
---|
152 | if(object->Enum()==RgbEnum){
|
---|
153 |
|
---|
154 | Rgb* rgb=(Rgb*)object;
|
---|
155 |
|
---|
156 | if(rgb->InAnalysis(analysis_type)){
|
---|
157 |
|
---|
158 | /*we found an rgb, increment counter, so that row index for Rmg is up to date: */
|
---|
159 | count++;
|
---|
160 |
|
---|
161 |
|
---|
162 | nodeid1=rgb->GetNodeId1();
|
---|
163 | nodeid2=rgb->GetNodeId2();
|
---|
164 | dof=rgb->GetDof();
|
---|
165 |
|
---|
166 | /*For this rgb, find the nodes that go with it: */
|
---|
167 | node1=(Node*)nodes->GetObjectById(NULL,nodeid1);
|
---|
168 | node2=(Node*)nodes->GetObjectById(NULL,nodeid2);
|
---|
169 |
|
---|
170 | if ((node1 && !node2) || (!node1 && node2)){
|
---|
171 | /*we are missing one node, not good!*/
|
---|
172 | ISSMERROR("%s%p%s%p"," in Rgb, missing one node. node1: ",node1," node2: ",node2);
|
---|
173 | }
|
---|
174 |
|
---|
175 | if(!node1 && !node2){
|
---|
176 | /*That's ok, this Rgb can't find those nodes, so leave them alone. They are probably not on this
|
---|
177 | * cpu!*/
|
---|
178 | }
|
---|
179 | else{
|
---|
180 | /*Ok, this cpu owns both nodes. Put dof for node1 into m set, unless it is already there,
|
---|
181 | * in which case node2 gets into the m set: */
|
---|
182 | if(node1->DofIsInMSet(dof-1)){
|
---|
183 | node2->DofInMSet(dof-1);
|
---|
184 | }
|
---|
185 | else{
|
---|
186 | node1->DofInMSet(dof-1);
|
---|
187 | }
|
---|
188 |
|
---|
189 | /*Plug values into Rmg. We essentially want dofs from node1 and node2 to be the
|
---|
190 | *same: */
|
---|
191 | dof1=node1->GetDof(dof-1); //matlab indexing
|
---|
192 | dof2=node2->GetDof(dof-1); //matlab indexing
|
---|
193 |
|
---|
194 | MatSetValue(Rmg,count,dof1,1.0,INSERT_VALUES);
|
---|
195 | MatSetValue(Rmg,count,dof2,-1.0,INSERT_VALUES);
|
---|
196 |
|
---|
197 | }
|
---|
198 | }
|
---|
199 | }
|
---|
200 | }
|
---|
201 | }
|
---|
202 | /*}}}*/
|
---|