test_propagators_00001.cpp
1 /*---------------------------------------------------------------------------*\
2  *
3  * mimmo
4  *
5  * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6  *
7  * -------------------------------------------------------------------------
8  * License
9  * This file is part of mimmo.
10  *
11  * mimmo is free software: you can redistribute it and/or modify it
12  * under the terms of the GNU Lesser General Public License v3 (LGPL)
13  * as published by the Free Software Foundation.
14  *
15  * mimmo is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18  * License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with mimmo. If not, see <http://www.gnu.org/licenses/>.
22  *
23  \ *---------------------------------------------------------------------------*/
24 
25 #include "mimmo_propagators.hpp"
26 
27 
28 // =================================================================================== //
43 // =================================================================================== //
44 
45 mimmo::MimmoSharedPointer<mimmo::MimmoObject> createTestVolumeMesh(std::vector<long> &bcdir1_vertlist, std::vector<long> &bcdir2_vertlist){
46 
47  std::array<double,3> center({{0.0,0.0,0.0}});
48  double radiusin(2.0), radiusout(5.0);
49  double azimuthin(0.0), azimuthout(0.5*BITPIT_PI);
50  double heightbottom(-1.0), heighttop(1.0);
51  int nr(6), nt(10), nh(6);
52 
53  double deltar = (radiusout - radiusin)/ double(nr);
54  double deltat = (azimuthout - azimuthin)/ double(nt);
55  double deltah = (heighttop - heightbottom)/ double(nh);
56 
57  std::vector<std::array<double,3> > verts ((nr+1)*(nt+1)*(nh+1));
58 
59  int counter = 0;
60  for(int k=0; k<=nh; ++k){
61  for(int j=0; j<=nt; ++j){
62  for(int i=0; i<=nr; ++i){
63  verts[counter][0] =(radiusin + i*deltar)*std::cos(azimuthin + j*deltat);
64  verts[counter][1] =(radiusin + i*deltar)*std::sin(azimuthin + j*deltat);
65  verts[counter][2] =(heightbottom + k*deltah);
66  ++counter;
67  }
68  }
69  }
70 
71  //create the volume mesh mimmo.
73  mesh->getPatch()->reserveVertices((nr+1)*(nt+1)*(nh+1));
74 
75  //pump up the vertices
76  for(const auto & vertex : verts){
77  mesh->addVertex(vertex); //automatic id assigned to vertices.
78  }
79  mesh->getPatch()->reserveCells(nr*nt*nh);
80 
81  //create connectivities for hexa elements
82  std::vector<long> conn(8,0);
83  for(int k=0; k<nh; ++k){
84  for(int j=0; j<nt; ++j){
85  for(int i=0; i<nr; ++i){
86  conn[0] = (nr+1)*(nt+1)*k + (nr+1)*j + i;
87  conn[1] = (nr+1)*(nt+1)*k + (nr+1)*j + i+1;
88  conn[2] = (nr+1)*(nt+1)*k + (nr+1)*(j+1) + i+1;
89  conn[3] = (nr+1)*(nt+1)*k + (nr+1)*(j+1) + i;
90  conn[4] = (nr+1)*(nt+1)*(k+1) + (nr+1)*j + i;
91  conn[5] = (nr+1)*(nt+1)*(k+1) + (nr+1)*j + i+1;
92  conn[6] = (nr+1)*(nt+1)*(k+1) + (nr+1)*(j+1) + i+1;
93  conn[7] = (nr+1)*(nt+1)*(k+1) + (nr+1)*(j+1) + i;
94  mesh->addConnectedCell(conn, bitpit::ElementType::HEXAHEDRON);
95  }
96  }
97  }
98 
99  mesh->updateAdjacencies();
100  mesh->updateInterfaces();
101  mesh->update();
102 
103  bcdir1_vertlist.clear();
104  bcdir2_vertlist.clear();
105  bcdir1_vertlist.reserve(mesh->getNVertices());
106  bcdir2_vertlist.reserve(mesh->getNVertices());
107 
108  for(int k=0; k<=nh; ++k){
109  for(int i=0; i<=nr; ++i){
110  bcdir1_vertlist.push_back((nr+1)*(nt+1)*k + i);
111  bcdir2_vertlist.push_back((nr+1)*(nt+1)*k + (nr+1)*nt + i);
112  }
113  }
114 
115  return mesh;
116 }
117 
118 
119 // =================================================================================== //
120 
121 /*
122  Testing scalar and vector field propagation.
123 */
124 int test1() {
125 
126  std::vector<long> bc1list, bc2list;
127  mimmo::MimmoSharedPointer<mimmo::MimmoObject> mesh = createTestVolumeMesh(bc1list, bc2list);
128  //serial test.
129  livector1D cellInterfaceList1 = mesh->getInterfaceFromVertexList(bc1list, true, true);
130  livector1D cellInterfaceList2 = mesh->getInterfaceFromVertexList(bc2list, true, true);
131 
132  //create the portion of boundary mesh carrying Dirichlet conditions
134  bdirMesh->getPatch()->reserveVertices(bc1list.size()+bc2list.size());
135  bdirMesh->getPatch()->reserveCells(cellInterfaceList1.size()+cellInterfaceList2.size());
136 
137  for(auto & val : bc1list){
138  bdirMesh->addVertex(mesh->getVertexCoords(val), val);
139  }
140  for(auto & val : bc2list){
141  bdirMesh->addVertex(mesh->getVertexCoords(val), val);
142  }
143  for(auto & val : cellInterfaceList1){
144  int sizeconn =mesh->getInterfaces().at(val).getConnectSize();
145  long * conn = mesh->getInterfaces().at(val).getConnect();
146  bdirMesh->addConnectedCell(std::vector<long>(&conn[0], &conn[sizeconn]),
147  bitpit::ElementType::QUAD, val);
148  }
149  for(auto & val : cellInterfaceList2){
150  int sizeconn =mesh->getInterfaces().at(val).getConnectSize();
151  long * conn = mesh->getInterfaces().at(val).getConnect();
152  bdirMesh->addConnectedCell(std::vector<long>(&conn[0], &conn[sizeconn]),
153  bitpit::ElementType::QUAD, val);
154  }
155 
156  bdirMesh->updateAdjacencies();
157  bdirMesh->update();
158 
159  bool check = false;
160  long targetNode = (10 +1)*(6+1)*3 + (6+1)*5 + 3;
161 
162 //TESTING THE SCALAR PROPAGATOR //////
163  // and the scalar field of Dirichlet values on its nodes.
164  mimmo::MimmoPiercedVector<double> bc_surf_field;
165  bc_surf_field.setGeometry(bdirMesh);
167  bc_surf_field.reserve(bdirMesh->getNVertices());
168  for(auto & val : bc1list){
169  bc_surf_field.insert(val, 10.0);
170  }
171  for(auto & val : bc2list){
172  bc_surf_field.insert(val, 0.0);
173  }
174 
175  // Now create a PropagateScalarField and solve the laplacian.
176  mimmo::PropagateScalarField * prop = new mimmo::PropagateScalarField();
177  prop->setName("test00001_PropagateScalarField");
178  prop->setGeometry(mesh);
179  prop->addDirichletBoundaryPatch(bdirMesh);
180  prop->addDirichletConditions(&bc_surf_field);
181  prop->setDamping(false);
182  prop->setPlotInExecution(true);
183 
184  mesh->getPatch()->write("mesh");
185 
186  prop->exec();
187 
188  auto values = prop->getPropagatedField();
189 
190  check = check || (std::abs(values->at(targetNode)-5.0) > 1.0E-6);
191 
192 //TESTING THE VECTOR PROPAGATOR //////
193  // and the scalar field of Dirichlet values on its nodes.
195  bc_surf_3Dfield.setGeometry(bdirMesh);
197  bc_surf_3Dfield.reserve(bdirMesh->getNVertices());
198  for(auto & val : bc1list){
199  bc_surf_3Dfield.insert(val, {{10.0, 7.0, -4.0}});
200  }
201  for(auto & val : bc2list){
202  bc_surf_3Dfield.insert(val, {{0.0,0.0,0.0}});
203  }
204 
205  // Now create a PropagateScalarField and solve the laplacian.
206  mimmo::PropagateVectorField * prop3D = new mimmo::PropagateVectorField();
207  prop3D->setName("test00001_PropagateVectorField");
208  prop3D->setGeometry(mesh);
209  prop3D->addDirichletBoundaryPatch(bdirMesh);
210  prop3D->addDirichletConditions(&bc_surf_3Dfield);
211  prop3D->setDamping(true);
212  prop3D->setDampingType(1);
213  prop3D->setDampingDecayFactor(1.0);
214  prop3D->setDampingInnerDistance(0.5);
215  prop3D->setDampingOuterDistance(3.5);
216 
217  prop3D->setPlotInExecution(true);
218 
219  prop3D->exec();
220 
221  auto values3D = prop3D->getPropagatedField();
222  check = check || (norm2(values3D->at(targetNode)-std::array<double,3>({{5.0,3.5,-2.0}})) > 1.0E-6);
223 
224  delete prop3D;
225  delete prop;
226 
227  return check;
228 }
229 
230 // =================================================================================== //
231 
232 int main( int argc, char *argv[] ) {
233 
234  BITPIT_UNUSED(argc);
235  BITPIT_UNUSED(argv);
236 
237 #if MIMMO_ENABLE_MPI
238  MPI_Init(&argc, &argv);
239 #endif
240 
241  int val = 1;
242  try{
243  val = test1() ;
244  }
245  catch(std::exception & e){
246  std::cout<<"test_propagators_00001 exited with an error of type : "<<e.what()<<std::endl;
247  return 1;
248  }
249 #if MIMMO_ENABLE_MPI
250  MPI_Finalize();
251 #endif
252 
253  return val;
254 }
MimmoObject is the basic geometry container for mimmo library.
std::vector< long > livector1D
void setGeometry(MimmoSharedPointer< MimmoObject > geo)
void setDataLocation(MPVLocation loc)