Skip to content

Commit d6167f4

Browse files
author
Roberto Di Remigio
committed
Add interface functions to Helmut's PWC code, written by Ville in 2009-2010
1 parent 81f5245 commit d6167f4

File tree

1 file changed

+335
-0
lines changed

1 file changed

+335
-0
lines changed

src/attic/dalton_wem.c

Lines changed: 335 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,335 @@
1+
#include <math.h>
2+
#include <time.h>
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include <string.h>
7+
#include "constants.h"
8+
#include "intvector.h"
9+
#include "vector2.h"
10+
#include "vector3.h"
11+
#include "sparse2.h"
12+
#include "basis.h"
13+
#include "dwt.h"
14+
#include "WEM.h"
15+
#include "WEMRHS.h"
16+
#include "WEMPCG.h"
17+
#include "WEMPGMRES.h"
18+
#include "compression.h"
19+
#include "init_points.h"
20+
#include "interpolate.h"
21+
#include "read_points.h"
22+
#include "postproc.h"
23+
#include "topology.h"
24+
#include "energy.h"
25+
#include "cubature.h"
26+
#include "data.h"
27+
#include "kern.h"
28+
#include "gauss_square.h"
29+
#include "dalton_wem.h"
30+
31+
32+
#if !defined pi
33+
#define pi 3.1415926535897932385
34+
#endif
35+
36+
sparse2 S; /* komprimierte Steifigkeitsmatrix */
37+
vector3 *P; /* Punkteliste der Einskalenbasis */
38+
unsigned int **F; /* Elementliste der Einskalenbasis */
39+
vector3 ****T; /* Oberflaecheninterpolation */
40+
vector3 ***U; /* Knotenpunkte */
41+
unsigned int nf; /* Laenge von F */
42+
unsigned int p; /* Anzahl der Patches */
43+
unsigned int M; /* 2^M*2^M Elemente pro Patch */
44+
element *E; /* hierarchische Elementliste */
45+
wavelet *W; /* Liste der Wavelets */
46+
double *v; /* approximierter Dichtevektor */
47+
48+
/*
49+
* Initializes the great WEM machine!
50+
*
51+
* int (out) - number of potential points
52+
*
53+
* return 0 - if all ok
54+
*
55+
*/
56+
int dalton_wem_initialize_(int *num_points, double *da, double *db, double *ddp,
57+
double *apriori, double *aposteriori){
58+
59+
char filename[80]="cavity.dat";
60+
61+
*da=a;
62+
*db=b;
63+
*ddp=dp;
64+
65+
/* Initialisierung */
66+
read_points(&U,&p,&M,filename);
67+
nf = p*(1<<M)*(1<<M); /* Anzahl der Patches */
68+
69+
/* Topologie bestimmen */
70+
init_interpolate(&T,U,p,M);
71+
gennet(&P,&F,U,p,M);
72+
free_points(&U,p,M);
73+
74+
/* erstelle Element-/Waveletliste */
75+
generate_elementlist(&E,P,F,p,M);
76+
generate_waveletlist(&W,E,p,M);
77+
set_quadrature_level(W,E,p,M);
78+
simplify_waveletlist(W,E,p,M);
79+
complete_elementlist(W,E,p,M);
80+
81+
/* berechne a-priori Kompression */
82+
compression(&S,W,E,p,M,apriori);
83+
84+
/* Steifigkeitsmatrix aufstellen */
85+
WEM(&S,W,P,E,T,p,M);
86+
87+
/* berechne a-posteriori */
88+
postproc(&S,W,E,p,M,aposteriori);
89+
90+
/* Number of potential points should be something like
91+
* [Number of parameter domains]*[2^(patch level)]**2*[quadrature level]**2
92+
*/
93+
94+
// Small chance for an error here..
95+
*num_points = nf * (general_quadrature_level+1)*(general_quadrature_level+1);
96+
97+
v = NULL;
98+
99+
if(general_quadrature_level!=0) {
100+
printf("Varo saatana! general_quadrature_level!=0!\n");
101+
return -1;
102+
}
103+
104+
return 0; // perhaps one should check for unsufficient memory etc.
105+
}
106+
107+
/*
108+
* Gets points for potential evaluation
109+
*
110+
* data[number of potential points] (out) :
111+
* [parameter domain][patch_level_y][patch_level_x][quadrature point]
112+
* double * (out) - [x1,x2, ...]
113+
* double * (out) - [y1,y2, ...]
114+
* double * (out) - [z1,z2, ...]
115+
* memory should be provided by dalton
116+
*
117+
*/
118+
void dalton_wem_get_potential_coordinates_(double *xp, double *yp, double *zp, double *carea){
119+
120+
unsigned int i1, i2, i3, k, g, index;
121+
unsigned int n = 1 << M;
122+
vector2 s,t;
123+
vector3 res;
124+
double h = 1./n;
125+
cubature *Q;
126+
double totalArea=0.0;
127+
128+
g = general_quadrature_level;
129+
init_Gauss_Square(&Q,g+1);
130+
131+
index = 0;
132+
for (i1=0; i1<p; i1++){ /* sum over parameter domains */
133+
s.y = 0;
134+
for (i2=0; i2<n; i2++){
135+
s.x = 0;
136+
for (i3=0; i3<n; i3++){ /* sum over patches */
137+
138+
for (k=0; k<Q[g].nop; k++){ /* sum over quadrature (g=2->nop=3*3) */
139+
t = vector2_add(s,vector2_Smul(h,Q[g].xi[k]));
140+
res = Chi(t,T[i1],M);
141+
xp[index] = res.x;
142+
yp[index] = res.y;
143+
zp[index] = res.z;
144+
totalArea += h*h*Q[g].w[k]*vector3_norm(n_Chi(t,T[i1],M));
145+
index += 1;
146+
}
147+
148+
s.x += h;
149+
}
150+
s.y += h;
151+
}
152+
}
153+
154+
*carea=totalArea;
155+
}
156+
157+
158+
void dalton_wem_get_areas_normals_(double *as, double *xn, double *yn, double *zn){
159+
160+
unsigned int i1, i2, i3, k, g, index;
161+
unsigned int n = 1 << M;
162+
vector2 s,t;
163+
vector3 res;
164+
double h = 1./n;
165+
cubature *Q;
166+
//double totalArea=0.0;
167+
168+
g = general_quadrature_level;
169+
init_Gauss_Square(&Q,g+1);
170+
171+
index = 0;
172+
for (i1=0; i1<p; i1++){ /* sum over parameter domains */
173+
s.y = 0;
174+
for (i2=0; i2<n; i2++){
175+
s.x = 0;
176+
for (i3=0; i3<n; i3++){ /* sum over patches */
177+
178+
for (k=0; k<Q[g].nop; k++){ /* sum over quadrature (g=2->nop=3*3) */
179+
t = vector2_add(s,vector2_Smul(h,Q[g].xi[k]));
180+
res = n_Chi(t,T[i1],M);
181+
xn[index] = res.x;
182+
yn[index] = res.y;
183+
zn[index] = res.z;
184+
as[index] = h*h*Q[g].w[k]*vector3_norm(n_Chi(t,T[i1],M));
185+
index += 1;
186+
}
187+
188+
s.x += h;
189+
}
190+
s.y += h;
191+
}
192+
}
193+
}
194+
195+
196+
/*
197+
* Calculates surface polarization charges
198+
*
199+
* int * (in) - maximum number of charge points
200+
* int * (out) - number of charges
201+
* double * (in) - potential values at pre-specified points
202+
* double * (out) - resulting charges at the same points
203+
* (allocate in DALTON, should be larger than #(potential))
204+
* double * (out) - positions of charges [x1,x2, ...]
205+
* double * (out) - positions of charges [y1,y2, ...]
206+
* double * (out) - positions of charges [z1,z2, ...]
207+
*
208+
*/
209+
void dalton_wem_get_charges_(int *max_charges, int *num_charges, double *potential, double *charges){
210+
211+
// This version uses only potential (not field)
212+
213+
unsigned int i;
214+
215+
// nf on oikea maara varauksille!
216+
// potentiaalia voidaan evaluoida useammassakin paikkaa, mutta se on painotettu
217+
// quadraturen kertoimilla s.e. varaus on vakio (tai varaus*quadrature * potentiaal)
218+
219+
*num_charges=nf*(general_quadrature_level+1)*(general_quadrature_level+1);
220+
if(*max_charges<*num_charges) {
221+
*num_charges=0;
222+
return;
223+
}
224+
225+
if(v==NULL) v = (double*) calloc(*num_charges,sizeof(double)); /* initial guess? */
226+
memset(v,*num_charges*sizeof(double),0);
227+
memset(charges,*max_charges*sizeof(double),0);
228+
229+
WEMRHS2D(charges,W,E,T,p,M,potential);
230+
WEMPCG(&S,charges,v,eps,p,M);
231+
232+
tdwtKon(v,M,nf);
233+
234+
double h=1.0/(1<<M);
235+
for(i=0;i<nf;i++) charges[i]=v[i]*h; // kertaa quadrature level... <- oikeasti kunnon quadrature kertoimilla
236+
// *num_charges=nf;
237+
}
238+
239+
void dalton_wem_get_charges2_(int *max_charges, int *num_charges, double *fieldx,
240+
double *fieldy,double *fieldz, double *charges){
241+
242+
// Field version
243+
244+
unsigned int i;
245+
246+
// nf on oikea maara varauksille!
247+
// potentiaalia voidaan evaluoida useammassakin paikkaa, mutta se on painotettu
248+
// quadraturen kertoimilla s.e. varaus on vakio (tai varaus*quadrature * potentiaal)
249+
250+
*num_charges=nf*(general_quadrature_level+1)*(general_quadrature_level+1);
251+
if(*max_charges<*num_charges) {
252+
*num_charges=0;
253+
return;
254+
}
255+
256+
if(v==NULL) v = (double*) calloc(*num_charges,sizeof(double)); /* initial guess? */
257+
258+
WEMRHS1D(charges,W,E,T,p,M,fieldx,fieldy,fieldz);
259+
WEMPGMRES1(&S,charges,v,eps,p,M);
260+
261+
tdwtKon(v,M,nf);
262+
263+
double h=1.0/(1<<M);
264+
// kertaa quadrature level... <- oikeasti pitäis painottaa potentiaalia quadraturella (kai)
265+
for(i=0;i<nf;i++) charges[i]=v[i]*h;
266+
*num_charges=nf;
267+
}
268+
269+
270+
/*
271+
* Calculates the total energy
272+
*
273+
* double *potential; Potential points!
274+
* double *energy; Results
275+
*
276+
*/
277+
void dalton_wem_energy_(double *potential, double *energy){
278+
279+
unsigned int n = 1 << M; /* n*n Patches pro Parametergebiet */
280+
unsigned int i1, i2, i3; /* Laufindizes fuer Ansatzfunktion */
281+
unsigned int zi; /* Zeilenindex hieraus: zi = i1*(n*n)+i2*n+i3 */
282+
cubature *Q; /* Kubatur-Formeln */
283+
/*unsigned int g = 2; */ /* Quadraturgrad */
284+
unsigned int g = 0; /* g=1, no difference wrt g=2 */
285+
unsigned int k; /* Laufindex fuer Quadratur */
286+
vector2 s; /* Linker, unterer Eckpunkt des Patches zi */
287+
vector2 t; /* Auswertepunkte der Gaussquadratur */
288+
double E; /* Energie */
289+
double h = 1./n; /* Schrittweite */
290+
double C = 0.0;
291+
unsigned int index;
292+
293+
if(v==NULL) exit(-102);
294+
295+
/* Initialisierung */
296+
g = general_quadrature_level;
297+
init_Gauss_Square(&Q,g+1); /* Kubatur-Formeln */
298+
299+
/* Berechnung des Fehlers */
300+
index=0;
301+
E = zi = 0;
302+
for (i1=0; i1<p; i1++) /* sum over parameter domains */
303+
{ s.y = 0;
304+
for (i2=0; i2<n; i2++)
305+
{ s.x = 0;
306+
for (i3=0; i3<n; i3++) /* zeilenweise Durchnumerierung der Patches zi = (i1,i2,i3) */
307+
{ for (k=0; k<Q[g].nop; k++) /* sum over quadrature points (nop=3*3 for g=2) */
308+
{ t = vector2_add(s,vector2_Smul(h,Q[g].xi[k]));
309+
/* E += Q[g].w[k]*v[zi]*f(Chi(t,T[i1],m)); */
310+
E += Q[g].w[k]*v[zi]*potential[index];
311+
index += 1;
312+
C += Q[g].w[k]*v[zi];
313+
}
314+
s.x += h;
315+
zi++;
316+
}
317+
s.y += h;
318+
}
319+
}
320+
E = -0.5*h*E; /* correct scaling */
321+
322+
free_Gauss_Square(&Q,g+1);
323+
*energy=E;
324+
}
325+
326+
void dalton_wem_finalize_(){
327+
if(v!=NULL) free(v);
328+
free_waveletlist(&W,p,M);
329+
free_elementlist(&E,p,M);
330+
free_interpolate(&T,p,M);
331+
free_patchlist(&F,nf);
332+
free_sparse2(&S);
333+
free(P);
334+
}
335+

0 commit comments

Comments
 (0)